home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1996
/
MacHack 1996.toast
/
Presentations
/
Presentations ’91
/
MPW Stand-Alone Libraries
/
UMakeSA.incl.p
< prev
next >
Wrap
Text File
|
1991-06-13
|
8KB
|
316 lines
{--------------------------------------------------------------------------------------------------}
{$S TInit}
{ Initialize our tool. First initialize the parent, then ourself. }
PROCEDURE TMakeSA.IMakeSA;
VAR
aDynamicArray: TDynamicArray;
aString: StringHandle;
fi: FailInfo;
PROCEDURE HdlFailure(error: Integer; message: LongInt);
BEGIN
IF (aDynamicArray <> NIL) THEN aDynamicArray.Free;
IF (aString <> NIL) THEN DisposHandle(Handle(aString));
END;
BEGIN
fFileNames := NIL;
fMainName := NIL;
SELF.ITool;
CatchFailures(fi, HdlFailure);
aDynamicArray := NIL;
New(aDynamicArray);
FailNil(aDynamicArray);
aDynamicArray.IDynamicArray(0, SizeOf(FileSpec));
fFileNames := aDynamicArray;
fFileType := kDfltFileType;
fFileCreator := kDfltFileCreator;
fMainType := kDfltMainSeg;
fMainID := kDfltRsrcID;
aString := NIL;
aString := StringHandle(NewHandle(SIZEOF(STR255)));
FailNil(aString);
fMainName := aString;
fMainName^^[0] := CHR(0); { Set it to empty string }
fDoMultiSeg := FALSE;
fOtherSegsType := kDfltOtherSeg;
Success(fi);
END;
{--------------------------------------------------------------------------------------------------}
{$S TInit}
{ Whenever the option '-help' is found, the tool calls this method }
{ to display the syntax on how to use the tool. }
PROCEDURE TMakeSA.DoShowUsage; OVERRIDE;
PROCEDURE HelpLine(theStr: Str255);
BEGIN
WriteLn(Diagnostic, theStr);
END;
BEGIN
HelpLine('MakeSA # Software Ventures'' stand alone code tool');
HelpLine('MakeSA [option…] [file…] ≥ progress');
HelpLine(' -ct type # Set resource type of non-main code segments (default = DUDE)');
HelpLine(' -fc type # Set file type of output file (default = rsrc)');
HelpLine(' -ft creator # Set file creator of output file (default = RSED)');
HelpLine(' -help # Return this help text');
HelpLine(' -id integer # Set the resource id of the main segment (default = 128)');
HelpLine(' -mn name # Set the resource name of the main segment (default = '''')');
HelpLine(' -mt type # Set the resource type of the main segment (default = DUDE)');
{
HelpLine(' -o filename # Name of the output file (default = input.dude)');
}
HelpLine(' -[No]P # Report progress (default = NoP)');
HelpLine(' -[No]S # Allow multi-segmented stand alone code (default = NoS)');
HelpLine(' -[No]T # Report elapsed time (default = NoT)');
END;
{--------------------------------------------------------------------------------------------------}
{$S TInit}
{ Install our keywords for MakeSA. }
PROCEDURE TMakeSA.InstallKeyWords; OVERRIDE;
BEGIN
INHERITED InstallKeyWords; { Do the default key words }
InstallKeyWord('CT', kwCType);
InstallKeyWord('FC', kwFCreator);
InstallKeyWord('FT', kwFType);
InstallKeyWord('ID', kwMID);
InstallKeyWord('MN', kwMName);
InstallKeyWord('MT', kwMType);
{ InstallKeyWord('O', kwOut); } { Not ready to support this yet }
InstallKeyWord('S', kwSeg);
InstallKeyWord('NOS', kwNoSeg);
END;
{--------------------------------------------------------------------------------------------------}
{$S TInit}
{ When the parser finds a file name, this routine is called to add it }
{ to the list of filenames gathered for proccessing into standalones. }
PROCEDURE TMakeSA.DoProcessFileArg(arg: Str255); OVERRIDE;
VAR
aFile: FileSpec;
BEGIN
aFile.fileName := NIL;
aFile.vRefNum := 0;
aFile.fileName := NewString(arg);
FailNil(aFile.fileName);
fFileNames.InsertElementsBefore(1, @aFile, 1);
END;
{--------------------------------------------------------------------------------------------------}
{$S TRes}
{ Simple little procedure for outputing progress lines }
PROCEDURE TMakeSA.DoShowProgress(aStr: Str255);
VAR
tempName: Str255;
BEGIN
IF fProgress THEN
BEGIN
tempName := fProgName;
WriteLn(Diagnostic, kErrorMarker, tempName, ' <<>> ', aStr);
WriteLn(Diagnostic, kErrorMarker);
PLFlush(Diagnostic);
END;
END;
{--------------------------------------------------------------------------------------------------}
{$S TInit}
{ Whenever an option with a '-' in front of it is found, the tool calls }
{ this method if the option is found in the list of keywords. We check }
{ to see if it's one of ours, and if so call GetNextArg to get the data }
{ associated with the option. If the option is not one of ours, we call }
{ the parent code to let it handle the option. }
PROCEDURE TMakeSA.DoProcessOptionArg(kw: Integer); OVERRIDE;
VAR
tempStr: Str255;
aLong: LongInt;
BEGIN
CASE kw OF
kwFType:
BEGIN
tempStr := SELF.GetNextArg;
IF (length(tempStr) <> 4) THEN
SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid file type>'))
ELSE
BlockMove(@tempStr[1], @fFileType, 4);
END;
kwFCreator:
BEGIN
tempStr := GetNextArg;
IF (length(tempStr) <> 4) THEN
SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid file creator>'))
ELSE
BlockMove(@tempStr[1], @fFileCreator, 4);
END;
kwMType:
BEGIN
tempStr := GetNextArg;
IF (length(tempStr) <> 4) THEN
SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid resource type>'))
ELSE
BlockMove(@tempStr[1], @fMainType, 4);
END;
kwMID:
BEGIN
tempStr := GetNextArg;
StringToNum(tempStr, aLong);
IF (aLong > maxInt) OR (aLong < -maxInt-1) THEN
SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid resource ID>'))
ELSE
fMainID := aLong;
END;
kwMName:
BEGIN
tempStr := GetNextArg;
fMainName^^ := tempStr;
END;
kwOut:
BEGIN
tempStr := GetNextArg;
{fOutName^^ := tempStr;} { not ready to support this yet }
END;
kwCType:
BEGIN
tempStr := GetNextArg;
IF (length(tempStr) <> 4) THEN
SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid resource type>'))
ELSE
BlockMove(@tempStr[1], @fOtherSegsType, 4);
END;
kwSeg:
BEGIN
fDoMultiSeg := TRUE;
END;
kwNoSeg:
BEGIN
fDoMultiSeg := FALSE;
END;
OTHERWISE
INHERITED DoProcessOptionArg(kw);
END;
END;
{--------------------------------------------------------------------------------------------------}
{$S TRes}
{ Given the list of files names, and a procedure to operate on each file }
{ walk through the list of files, handing each off to the procedure. }
PROCEDURE TMakeSA.ForEachFileDo(PROCEDURE DoToFile(aFile: FileSpec));
VAR
dummy: ArrayIndex;
FUNCTION ForThisItemDo(index: ArrayIndex): BOOLEAN;
LABEL 1234;
VAR
fi: FailInfo;
aFileSpec: FileSpec;
PROCEDURE HdlFailure(error: Integer; message: LongInt);
BEGIN
IF (error = resFNotFound) OR (error = fnfErr) THEN
GOTO 1234;
END;
BEGIN
fFileNames.GetElementsAt(index, @aFileSpec, 1);
CatchFailures(fi, HdlFailure);
SpinCursor(1);
DoToFile(aFileSpec);
Success(fi);
1234:
ForThisItemDo := FALSE;
END;
BEGIN
dummy := fFileNames.EachElementDoTil(ForThisItemDo, kIterateBackward);
END;
{--------------------------------------------------------------------------------------------------}
{$S TRes}
{ The Tool calls this method after it has successfully parsed the command line. }
{ Now, for each file found, massage it into a stand alone piece of code. }
PROCEDURE TMakeSA.DoToolAction; OVERRIDE;
VAR
aFile: FileSpec;
PROCEDURE SingleSegMassage(aFile: FileSpec);
VAR
aBuildSA: TSingleSegSA;
BEGIN
New(aBuildSA);
FailNIL(aBuildSA);
aBuildSA.ISingleSegSA(aFile, fMainType, fMainID, fMainName);
aBuildSA.DoIt;
aBuildSA.Free;
END;
PROCEDURE MultiSegMassage(aFile: FileSpec);
VAR
aBuildSA: TMultiSegSA;
BEGIN
New(aBuildSA);
FailNIL(aBuildSA);
aBuildSA.IMultiSegSA(aFile, fMainType, fMainID, fMainName, fOtherSegsType);
aBuildSA.DoIt;
aBuildSA.Free;
END;
BEGIN
IF (fFileNames.IsEmpty) THEN
BEGIN
fRetCode := RC_ParmErrs;
Stop('No files to operate on.');
END
ELSE IF (NOT fDoMultiSeg) THEN
ForEachFileDo(SingleSegMassage)
ELSE
ForEachFileDo(MultiSegMassage);
END;
{--------------------------------------------------------------------------------------------------}